/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.thesis.algorithm;

import java.io.DataOutputStream;
import java.util.LinkedList;
import com.thesis.utils.CONSTANTS;

public class Sequence {
	// Data from 1 file
	public LinkedList<SequenceElement> sequenceinFile = new LinkedList<SequenceElement>();
	public int BusRouteID = 0;

	public boolean add(SequenceElement e) {
		return sequenceinFile.add(e);
	}

	public int compareto(Sequence seq) {
		if (this.sequenceinFile == null || seq == null) {
			return sequenceinFile.size();
		}
		if (sequenceinFile.size() != seq.size()) {
			return this.size();
		}

		int count = 0;
		for (int i = 0; i < this.size(); i++) {
			// if (sequenceinFile.get(i).Observation!=seq.get(i).Observation)
			// return false;
			if (sequenceinFile.get(i).State != seq.get(i).State) {
				++count;
			}
		}

		return count;
	}

	public boolean compareLast(Sequence seq) {
		if (this.sequenceinFile == null || seq == null) {
			// TODO:
			return false;
		}
		if (sequenceinFile.size() != seq.size() || seq.size() == 0) {
			return false;
		}
		return (sequenceinFile.getLast().State == seq.getLast().State);

	}

	public SequenceElement get(int i) {
		return sequenceinFile.get(i);
	}

	public SequenceElement getFirst() {
		return sequenceinFile.getFirst();
	}

	public SequenceElement getLast() {
		return sequenceinFile.getLast();
	}

	public int size() {
		return sequenceinFile.size();
	}
	


	public Sequence refineSequence() {
		Sequence result = new Sequence();
		SequenceElement e = new SequenceElement(sequenceinFile.getFirst());
		char count = 0;
		
		for (SequenceElement seqel : sequenceinFile) {
			if (e.Observation != seqel.Observation || e.Lac != seqel.Lac|| e.State != seqel.State) {
				e.Repetition = count;
				result.add(e);
				count = seqel.Repetition;
				e = new SequenceElement(seqel);
			} else
				count+=seqel.Repetition;
		}

		e.Repetition = count;
		result.add(e);

		result.BusRouteID = BusRouteID;
		return result;
	}

	public Sequence refineSequenceWithDifferentState() {
		Sequence result = new Sequence();
		SequenceElement e = new SequenceElement();
		for (SequenceElement seqel : sequenceinFile) {
			if (e.Observation != seqel.Observation || e.State != seqel.State) {
				result.add(seqel);
			}
			e = seqel;
		}
		result.BusRouteID = this.BusRouteID;
		return result;
	}

	public String toString() {
            String result = "busID" + BusRouteID + ": ";
            for (int i = 0; i < sequenceinFile.size(); i++) {
			result += sequenceinFile.get(i).toString();
		}
		return result;
	}

	public int score() {
		int result = 0;
		for (int i = 0; i < sequenceinFile.size(); i++) {
			result += sequenceinFile.get(i).Repetition;
		}
		return result;
	}
	
	

	public LinkedList<Character> lookup(char observation) {
		// TODO: add element
		LinkedList<Character> result = new LinkedList<Character>();
		for (int i = 0; i < sequenceinFile.size(); i++) {
			if (sequenceinFile.get(i).Observation == observation) {
				result.add(sequenceinFile.get(i).State);
			}
		}
		return result;
	}


	public void writeBinary(DataOutputStream out) {
		if (out == null) {
			System.out.println("DataOutputStream out is null");
			return;
		}
		try {
			out.writeChar(CONSTANTS.MAXCHAR);
			out.writeShort(BusRouteID);
			for (SequenceElement el : sequenceinFile) {
				el.writeBinary(out);
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

	public void writeBinaryShorten(DataOutputStream out) {
		if (out == null) {
			System.out.println("DataOutputStream out is null");
			return;
		}
		try {
			out.writeChar(CONSTANTS.MAXCHAR);
			out.writeShort(BusRouteID);
			SequenceElement prev = null;
			char count = (char) -1;
			for (SequenceElement el : sequenceinFile) {
				count++;
				if (prev == null) {
					out.writeChar(count);
					el.writeBinary(out);
					prev = el;
				} else {
					if (prev.isEqual(el) != true) {
						out.writeChar(count);
						el.writeBinary(out);
					}
				}
			}
		} catch (Exception e1) {
			e1.printStackTrace();
		}
	}

    public int scorebefore(int start) {
        int result = 0;
		for (int i = 0; i < sequenceinFile.size() && i < start; i++) {
			result += sequenceinFile.get(i).Repetition;
		}
		return result;
    }
}
